package cn.getech.data.development.controller.offline;

import cn.getech.data.development.constant.ApplyStatusEnum;
import cn.getech.data.development.constant.StoreTableType;
import cn.getech.data.development.entity.dataMap.DataApplication;
import cn.getech.data.development.entity.dataMap.RollbackParam;
import cn.getech.data.development.model.dto.ApplyUserListDTO;
import cn.getech.data.development.model.dto.real.RealApproveQueryDTO;
import cn.getech.data.development.model.dto.real.RealApproveReturnDTO;
import cn.getech.data.development.service.DataApplicationService;
import cn.getech.data.development.service.TableInfoService;
import cn.getech.data.intelligence.common.utils.PageUtils;
import cn.getech.data.intelligence.common.utils.R;
import cn.getech.system.center.annotation.SysLog;
import cn.getech.system.center.constant.OperationModulesEnum;
import cn.getech.system.center.constant.OperationTypeEnum;
import cn.getech.system.center.constant.module.ModuleEnum;
import cn.getech.system.center.entity.SysUserEntity;
import cn.getech.system.center.utils.ShiroUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.google.common.collect.Maps;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;


/**
 * @description: 数据地图接口类
 * @author: wangzhaowen：kiss
 * @create: 2020/9/2 18:03
 * @version: 2020/9/2
 **/
@Slf4j
@Api(tags = "数据表信息")
@RestController
@RequestMapping("/bdp/tableInfo")
public class DataMapController {

    @Autowired
    private TableInfoService tableInfoService;

    @Autowired
    private DataApplicationService dataApplicationService;

    @ApiOperation("获取获取申请数据仓库列表")
    @PostMapping("/data-map")//  /data-development/bdp/tableInfo/data-map
    //@SysLog(value = "获取获取申请数据仓库列表", type = OperationTypeEnum.SELECTCODE, modulesType = OperationModulesEnum.TABLEMODELCODE, platformModuleType = ModuleEnum.DATA_MAP_MODULE_CODE)
    public R selectApplyListPage(@ApiParam(value = "{'table_name':'test','db_name':'test','applyStatus':0}")
                                 @RequestBody Map<String, Object> params) {
        JSONObject data = tableInfoService.selectApplyListPage(params);
        return R.okWithData(data);
    }

    /**
     * 获取数据表信息列表
     */
    @ApiOperation("获取数据表信息列表")
    @PostMapping("/listAll")
    //@SysLog(value = "获取数据仓库列表", type = OperationTypeEnum.SELECTCODE, modulesType = OperationModulesEnum.TABLEMODELCODE, platformModuleType = ModuleEnum.DATA_MAP_MODULE_CODE)
    //todo 0925
    //@RequiresPermissions({"bdp:tableInfo:list"})
    public R listAll(@ApiParam(value = "{'table_name':'test','db_name':'test'}") @RequestBody Map<String, Object> params) {
        Long userId = ShiroUtils.getUserId();
        params.put("create_per", userId);
        params.put("appUser", userId);
        params.put("sidx", "id");
        params.put("order", "desc");
        PageUtils page = tableInfoService.queryPage(params);
        return R.okWithPage(page);
    }


    /**
     * 获取数据实时表信息列表 (实时表)
     */
    @ApiOperation("获取数据实时表信息列表（实时表）")
    @PostMapping("/real/list")
    //@SysLog(value = "获取数据实时表信息列表 (实时表)", type = OperationTypeEnum.SELECTCODE, modulesType = OperationModulesEnum.TABLEMODELCODE, platformModuleType = ModuleEnum.DATA_MAP_MODULE_CODE)
    //todo 0925
    //@RequiresPermissions({"bdp:tableInfo:list"})
    public R realList(@RequestBody RealApproveQueryDTO realApproveQueryDTO) {
        realApproveQueryDTO.setUserId(ShiroUtils.getUserId().intValue());
        IPage<RealApproveReturnDTO> page = tableInfoService.realList(realApproveQueryDTO);
        return R.okWithPage(page);
    }

    @ApiOperation("我申请的数据仓库列表")
    @PostMapping("/list/own/apply")//  /data-development/bdp/tableInfo/list/own/apply
    //@SysLog(value = "我申请的数据仓库列表", type = OperationTypeEnum.SELECTCODE, modulesType = OperationModulesEnum.TABLEMODELCODE, platformModuleType = ModuleEnum.DATA_MAP_MODULE_CODE)
    public R listOwnApply(@ApiParam(value = "{'table_name':'test','db_name':'test'}")
                          @RequestBody Map<String, Object> params) {

        //如果前端传了创建人，则设置创建人ID
        if (params.get("userId") != null) {
            params.put("createUserId", params.get("userId"));
        }
        Long userId = ShiroUtils.getUserId();
        params.put("userId", userId);
        List<Integer> statusList = new ArrayList<>(3);
        statusList.add(ApplyStatusEnum.PASS.getType());
        statusList.add(ApplyStatusEnum.ROLLBACK.getType());
        statusList.add(ApplyStatusEnum.EXPIRED.getType());
        Integer tenantId = ShiroUtils.getTenantId();
        params.put("tenantId", tenantId);
        params.put("applyStatusIn", statusList);
        PageUtils data = tableInfoService.selectListOwnPage(params);
        return R.okWithData(data);
    }


    @ApiOperation("被授权的表(实时)")
    @PostMapping("/real/list/own/apply")//  /data-development/bdp/tableInfo/real/list/own/apply
    //@SysLog(value = "被授权的表(实时)", type = OperationTypeEnum.SELECTCODE, modulesType = OperationModulesEnum.TABLEMODELCODE, platformModuleType = ModuleEnum.DATA_MAP_MODULE_CODE)
    public R realListOwnApply(@RequestBody RealApproveQueryDTO realApproveQueryDTO) {
        Map<String, Object> params = new HashMap<>();
        Long userId = ShiroUtils.getUserId();
        params.put("userId", userId);
        List<Integer> statusList = new ArrayList<>(3);
        statusList.add(ApplyStatusEnum.PASS.getType());
        statusList.add(ApplyStatusEnum.ROLLBACK.getType());
        statusList.add(ApplyStatusEnum.EXPIRED.getType());
        params.put("applyStatusIn", statusList);
        IPage<RealApproveReturnDTO> page = tableInfoService.realApproveList(params, realApproveQueryDTO);
        return R.okWithData(new PageUtils<>(page));
    }



    @ApiOperation("我授权的数据仓库列表(离线表)")
    @PostMapping("/list/own/approve")//  /data-development/bdp/tableInfo/list/own/approve
    public R listOwnApprove(@ApiParam(value = "{'table_name':'test','db_name':'test'}")
                            @RequestBody Map<String, Object> params) {
        Long userId = ShiroUtils.getUserId();
        params.put("approveUserId", userId);
        Integer tenantId = ShiroUtils.getTenantId();
        params.put("tenantId", tenantId);
        PageUtils data = tableInfoService.selectListOwnPage(params);
        return R.okWithData(data);
    }

    @ApiOperation("我授权的数据仓库列表(实时表)")
    @PostMapping("/real/list/own/approve")//  /data-development/bdp/tableInfo/list/real/own/approve
    public R listOwnApprove(@RequestBody RealApproveQueryDTO realApproveQueryDTO) {
        log.info("/list/real/own/approve 我授权的数据仓库列表(实时表)参数接收:{}", JSON.toJSONString(realApproveQueryDTO));
        realApproveQueryDTO.setApproveUserId(ShiroUtils.getUserId().intValue());
        Map<String, Object> params = new HashMap<>();
        params.put("userId",realApproveQueryDTO.getUserId());
        Integer tenantId = ShiroUtils.getTenantId();
        params.put("tenantId", tenantId);
        IPage<RealApproveReturnDTO> page = tableInfoService.realApproveList(params, realApproveQueryDTO);
        return R.okWithData(new PageUtils<>(page));
    }

    @ApiOperation("实时数仓我授权的表 申请人列表")
    @GetMapping("/real/applyUserList")//
    public R applyUserList() {
        Integer userId = ShiroUtils.getUserId().intValue();
        List<JSONObject> jsonObjects = tableInfoService.applyUserList(userId, StoreTableType.ONLINE.getCode());
        return R.okWithData(jsonObjects);
    }
    @ApiOperation("离线数仓获取申请人列表")
    @GetMapping("/applyUserList")  // /data-development/bdp/tableInfo/applyUserList
    public R offapplyUserList() {
        Integer userId = ShiroUtils.getUserId().intValue();
        List<JSONObject> jsonObjects = tableInfoService.applyUserList(userId,StoreTableType.OFFLINE.getCode());
        return R.okWithData(jsonObjects);
    }
    @ApiOperation("被授权的表(实时) 创建人列表查询")
    @GetMapping("/offline/createUserList")//  /data-development/bdp/tableInfo/offline/createUserList
    public R offcreateUserList() {
        Map<String, Object> params = new HashMap<>();
        Long userId = ShiroUtils.getUserId();
        params.put("userId", userId);
        List<Integer> statusList = new ArrayList<>(3);
        statusList.add(ApplyStatusEnum.PASS.getType());
        statusList.add(ApplyStatusEnum.ROLLBACK.getType());
        statusList.add(ApplyStatusEnum.EXPIRED.getType());
        params.put("tableType", StoreTableType.OFFLINE.getCode());
        Integer tenantId = ShiroUtils.getTenantId();
        params.put("tenantId", tenantId);
        params.put("applyStatusIn", statusList);
        List<JSONObject> jsonObjects = tableInfoService.createUserList(statusList,params);
        return R.okWithData(jsonObjects);
    }

    @ApiOperation("被授权的表(实时) 创建人列表查询")
    @GetMapping("/real/createUserList")//   /data-development/bdp/tableInfo/real/createUserList
    public R createUserList() {
        Map<String, Object> params = new HashMap<>();
        Long userId = ShiroUtils.getUserId();
        params.put("userId", userId);
        params.put("tableType", StoreTableType.ONLINE.getCode());
        List<Integer> statusList = new ArrayList<>(3);
        statusList.add(ApplyStatusEnum.PASS.getType());
        statusList.add(ApplyStatusEnum.ROLLBACK.getType());
        statusList.add(ApplyStatusEnum.EXPIRED.getType());
        Integer tenantId = ShiroUtils.getTenantId();
        params.put("tenantId", tenantId);
        params.put("applyStatusIn", statusList);
        List<JSONObject> jsonObjects = tableInfoService.createUserList(statusList,params);
        return R.okWithData(jsonObjects);
    }


    @ApiOperation("申请授权获取表和字段接口")
    @GetMapping("/apply/info")//  /data-development/bdp/tableInfo/apply/info
    @SysLog(value = "申请授权获取表和字段接口", type = OperationTypeEnum.GETCODE, modulesType = OperationModulesEnum.TABLEMODELCODE, platformModuleType = ModuleEnum.DATA_MAP_MODULE_CODE)
    public R applyInfo(@ApiParam(value = "{'id':'1'") Integer tableId,
                       Long applyId, Integer tableType) {
        DataApplication data = dataApplicationService.queryApplyInfo(tableId, applyId, tableType);
        if (data == null) {
            return R.error("申请数据不存在！");
        }
        return R.okWithData(data);
    }

    @ApiOperation("申请数据仓库提交")
    @PostMapping("/apply/save")//  /data-development/bdp/tableInfo/apply/save
    @SysLog(value = "表申请", type = OperationTypeEnum.APPLYCODE, modulesType = OperationModulesEnum.TABLEMODELCODE,platformModuleType = ModuleEnum.DATA_MAP_MODULE_CODE)
    public R saveApplyInfo(@RequestBody DataApplication param) {
        if (param.getApplyType() == null) {
            return R.error("申请的表类型不能为空！");
        }
        if (StringUtils.isEmpty(param.getApplyReason())) {
            return R.error("申请理由不能为空！");
        }
        if (param.getApplyReason().length() > 200) {
            return R.error("申请理由超过200个字符！");
        }
        if (param.getEffectiveDeadline() != null) {
            long now = new Date().getTime();
            if (param.getEffectiveDeadline().getTime() < now) {
                return R.error("有效截止日期必须大于当前时间!");
            }
        }
        dataApplicationService.saveApplyInfo(param);
        return R.ok();
    }

    @ApiOperation("申请审批")
    @PostMapping("/apply/approve")//  /data-development/bdp/tableInfo/apply/approve
    @SysLog(value = "表审批", type = OperationTypeEnum.AUDITCODE, modulesType = OperationModulesEnum.TABLEMODELCODE, platformModuleType = ModuleEnum.DATA_MAP_MODULE_CODE)
    public R dataApprove(@ApiParam(value = "{'id':'123','applyStatus':2}")
                         @RequestBody DataApplication param) {
        if (param.getId() == null) {
            return R.error("申请id不能为空！");
        }
        if (param.getApplyStatus() == null) {
            return R.error("申请状态不能为空!");
        }
        if (ApplyStatusEnum.REJECT.getType().equals(param.getApplyStatus())) {
            if (StringUtils.isEmpty(param.getRejectionReason())) {
                return R.error("回收理由不能为空！");
            }
            if (param.getRejectionReason().length() > 200) {
                return R.error("回收理由超过200个字符！");
            }
        }
        if (ApplyStatusEnum.PASS.getType().equals(param.getApplyStatus())) {
            if (StringUtils.isEmpty(param.getRejectionReason())) {
                return R.error("审批理由不能为空！");
            }
            if (param.getRejectionReason().length() > 200) {
                return R.error("审批理由超过200个字符！");
            }
        }
        dataApplicationService.dataApprove(param);
        return R.ok();
    }

    @ApiOperation("我的审批")
    @PostMapping("/approve/own/list")//  /data-development/bdp/tableInfo/approve/own/list
    //@SysLog(value = "我的审批", type = OperationTypeEnum.SELECTCODE, modulesType = OperationModulesEnum.TABLEMODELCODE, platformModuleType = ModuleEnum.DATA_MAP_MODULE_CODE)
    public R approveOwnList(@ApiParam(value = "{'applyUser':'test','applyStatus':0}")
                            @RequestBody Map<String, Object> params) {
        Long userId = ShiroUtils.getUserId();
        params.put("loginUser", userId);
        PageUtils page = dataApplicationService.approveOwnList(params);
        return R.okWithPage(page);
    }

    @ApiOperation("我的审批申请人列表")
    @GetMapping("/applicant/list")//  /data-development/bdp/tableInfo/approve/own/list
    public R applyListUser() {
        Set<ApplyUserListDTO> list = dataApplicationService.applyUserList();
        return R.okWithData(list);
    }

    @ApiOperation("我的申请")
    @PostMapping("/apply/own/list")//  /data-development/bdp/tableInfo/apply/own/list
    //@SysLog(value = "我的申请", type = OperationTypeEnum.SELECTCODE, modulesType = OperationModulesEnum.TABLEMODELCODE, platformModuleType = ModuleEnum.DATA_MAP_MODULE_CODE)
    public R applyOwnList(@ApiParam(value = "{'table_name':'test','applyStatus':0}")
                          @RequestBody Map<String, Object> params) {
        PageUtils page = dataApplicationService.applyOwnList(params);
        return R.okWithPage(page);
    }

    @ApiOperation("权限回收")
    @PostMapping("/apply/rollback/list")//  /data-development/bdp/tableInfo/apply/rollback/list
    //@SysLog(value = "我的申请", type = OperationTypeEnum.SELECTCODE, modulesType = OperationModulesEnum.TABLEMODELCODE, platformModuleType = ModuleEnum.DATA_MAP_MODULE_CODE)
    public R applyRollbackList(@ApiParam(value = "{'table_name':'test','applyStatus':0}")
                               @RequestBody Map<String, Object> params) {
        PageUtils page = dataApplicationService.applyRollbackList(params);
        return R.okWithPage(page);
    }

    @ApiOperation("权限回收申请人列表")
    @GetMapping("/rollback/apply/user/list")//  /data-development/bdp/tableInfo/apply/rollback/list
    //@SysLog(value = "我的申请", type = OperationTypeEnum.SELECTCODE, modulesType = OperationModulesEnum.TABLEMODELCODE, platformModuleType = ModuleEnum.DATA_MAP_MODULE_CODE)
    public R rollbackApplyUserList() {
        Set<ApplyUserListDTO>  applyUserListDTOS=dataApplicationService.rollbackApplyUserList();
        return R.okWithData(applyUserListDTOS);
    }

    @ApiOperation("权限回收")
    @PostMapping("/apply/rollback")//  /data-development/bdp/tableInfo/apply/rollback
    @SysLog(value = "权限回收", type = OperationTypeEnum.AUDITCODE, modulesType = OperationModulesEnum.TABLEMODELCODE, platformModuleType = ModuleEnum.DATA_MAP_MODULE_CODE)
    public R applyRollback(@ApiParam(value = "{'applyIds':'[123,12]','rejectionReason':2}")
                           @RequestBody RollbackParam param) {
        if (StringUtils.isEmpty(param.getRollbackReason())) {
            return R.error("回收理由不能为空！");
        }
        if (param.getRollbackReason().length() > 200) {
            return R.error("回收理由超过200个字符！");
        }
        if (CollectionUtils.isEmpty(param.getApplyIds())) {
            return R.error("申请id不能为空！");
        }
        dataApplicationService.applyRollback(param);
        return R.ok();
    }

    @ApiOperation("离线和实时数仓项目列表查询")
    @GetMapping("/apply/project/list")
    public R projectList(@RequestParam(value = "tableType", required = false) Integer tableType) {
        List<String> projectNames = dataApplicationService.projectList(tableType);
        return R.okWithData(projectNames);
    }

    @ApiOperation("实时数仓我授权的表  申请人列表查询")
    @GetMapping("/apply/user/list")
    public R listUser() {
        List<Map<String, Object>> users = dataApplicationService.listUser();
        return R.okWithData(users);
    }


}
